package lsp.base;

import java.net.DatagramPacket;
import java.nio.ByteBuffer;


public class LspPacket {
	
	private static final int MESSAGE_TYPE_LENGTH = 2;
	private static final int CONNECTION_ID_LENGTH = 2;
	private static final int SEQUENCE_NUMBER_LENGTH = 2;
	
	private MessageType messageType;
	private short connId;
	private short sequenceNumber;
	private byte[] payload = new byte[0];
	private PacketStatus packetStatus;

	public LspPacket(MessageType messageType, short connectionId, short sequenceNumber) {
		this.setMessageType(messageType);
		this.connId = connectionId;
		this.sequenceNumber = sequenceNumber;
	}
	
	public LspPacket(MessageType messageType, short connectionId, short sequenceNumber, byte[] payload) {
		this(messageType, connectionId, sequenceNumber);
		this.payload = payload;
	}
	
	public int getLength() {
		return MESSAGE_TYPE_LENGTH + CONNECTION_ID_LENGTH + SEQUENCE_NUMBER_LENGTH + payload.length;
	}
	
	private byte[] buildMessage() {
		ByteBuffer byteBuffer = ByteBuffer.allocate(getLength());
		byteBuffer.putShort(getMessageType().getCode());
		byteBuffer.putShort(connId);
		byteBuffer.putShort(sequenceNumber);
		byteBuffer.put(payload);
		return byteBuffer.array();
	}
	
	public DatagramPacket toDatagramPacket() {
		byte[] message = buildMessage();
		return new DatagramPacket(message, message.length);
	}
	
	public static LspPacket fromDatagramPacket(DatagramPacket datagramPacket) {
		byte[] data = datagramPacket.getData();
		ByteBuffer byteBuffer = ByteBuffer.wrap(data);
		MessageType packetMessageType = MessageType.values()[byteBuffer.getShort()];
		short packetConnectionId = byteBuffer.getShort();
		short packetSequenceNumber = byteBuffer.getShort();
		
		byte[] packetPayload = new byte[datagramPacket.getLength() - byteBuffer.position()]; 
		byteBuffer.get(packetPayload);
		
		LspPacket packet = new LspPacket(packetMessageType, packetConnectionId, packetSequenceNumber, packetPayload);
		return packet;
	}
	
	public short getConnId() {
		return connId;
	}

	public void setConnId(short connectionId) {
		this.connId = connectionId;
	}

	public short getSequenceNumber() {
		return sequenceNumber;
	}

	public void setSequenceNumber(short sequenceNumber) {
		this.sequenceNumber = sequenceNumber;
	}

	public byte[] getPayload() {
		return payload;
	}

	public void setPayload(byte[] payload) {
		this.payload = payload;
	}

	public MessageType getMessageType() {
		return messageType;
	}

	public void setMessageType(MessageType messageType) {
		this.messageType = messageType;
	}

	public PacketStatus getPacketStatus() {
		return packetStatus;
	}

	public void setPacketStatus(PacketStatus packetStatus) {
		this.packetStatus = packetStatus;
	}

	public Pack toPack() {
		return new Pack(connId, payload);
	}

}
